/**
 * Filename: ImagePipelineConfigFactory.java
 * @author  Firefly
 * @contact postfirefly@163.com
 * @time    2016/6/16 15:40
 */
package com.github.postsanf.yinian.utils;

import android.content.Context;
import android.graphics.Bitmap;

import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.internal.Supplier;
import com.facebook.common.util.ByteConstants;
import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory;
import com.facebook.imagepipeline.cache.MemoryCacheParams;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.decoder.ProgressiveJpegConfig;
import com.facebook.imagepipeline.image.ImmutableQualityInfo;
import com.facebook.imagepipeline.image.QualityInfo;
import com.facebook.imagepipeline.listener.RequestListener;
import com.facebook.imagepipeline.listener.RequestLoggingListener;
import com.squareup.okhttp.OkHttpClient;

import java.util.HashSet;
import java.util.Set;

public class ImagePipelineConfigFactory {
	private static final int MAX_HEAP_SIZE = (int) Runtime.getRuntime().maxMemory();
	public static final int MAX_DISK_CACHE_SIZE = 200 * ByteConstants.MB;
	public static final int MAX_MEMORY_CACHE_SIZE = MAX_HEAP_SIZE / 4;
	private static final String IMAGE_PIPELINE_CACHE_DIR = "imagepipeline_cache";
	private static ImagePipelineConfig sImagePipelineConfig;
	private static ImagePipelineConfig sOkHttpImagePipelineConfig;

	/**
	 * 使用Android自带的网络加载图片
	 */
    public static ImagePipelineConfig getImagePipelineConfig(Context context) {
        if (sImagePipelineConfig == null) {
            ImagePipelineConfig.Builder configBuilder = ImagePipelineConfig.newBuilder(context);
            configBuilder.setDownsampleEnabled(true);
            configBuilder.setProgressiveJpegConfig(mProgressiveJpegConfig);
            configBuilder.setBitmapsConfig(Bitmap.Config.ARGB_4444);
            configureCaches(configBuilder, context);
            configureLoggingListeners(configBuilder);
            configureOptions(configBuilder);
            sImagePipelineConfig = configBuilder.build();
        }
        return sImagePipelineConfig;
    }

	/**
	 * 使用OkHttp网络库加载图片
	 */
	public static ImagePipelineConfig getOkHttpImagePipelineConfig(Context context) {
		if (sOkHttpImagePipelineConfig == null) {
			OkHttpClient okHttpClient = new OkHttpClient();
			ImagePipelineConfig.Builder configBuilder =
					OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient);
			configBuilder.setDownsampleEnabled(true);
			configureCaches(configBuilder, context);
			configureLoggingListeners(configBuilder);
			sOkHttpImagePipelineConfig = configBuilder.build();
		}
		return sOkHttpImagePipelineConfig;
	}

	/**
	 * 配置内存缓存和磁盘缓存
	 */
	private static void configureCaches(
			ImagePipelineConfig.Builder configBuilder,
			Context context) {
		final MemoryCacheParams bitmapCacheParams = new MemoryCacheParams(
				MAX_MEMORY_CACHE_SIZE, 				   // Max total size of elements in the cache
				Integer.MAX_VALUE,                     // Max entries in the cache
				MAX_MEMORY_CACHE_SIZE,				   // Max total size of elements in eviction queue
				Integer.MAX_VALUE,                     // Max length of eviction queue
				Integer.MAX_VALUE);                    // Max cache entry size
		configBuilder
				.setBitmapMemoryCacheParamsSupplier(
						new Supplier<MemoryCacheParams>() {
							public MemoryCacheParams get() {
								return bitmapCacheParams;
							}
						})
				.setMainDiskCacheConfig(
						DiskCacheConfig.newBuilder()
								.setBaseDirectoryPath(context.getApplicationContext().getCacheDir())
								.setBaseDirectoryName(IMAGE_PIPELINE_CACHE_DIR)
								.setMaxCacheSize(MAX_DISK_CACHE_SIZE)
								.build());
	}

	private static void configureLoggingListeners(ImagePipelineConfig.Builder configBuilder) {
		Set<RequestListener> requestListeners = new HashSet<>();
		requestListeners.add(new RequestLoggingListener());
		configBuilder.setRequestListeners(requestListeners);
	}

	private static void configureOptions(ImagePipelineConfig.Builder configBuilder) {
		configBuilder.setDownsampleEnabled(true);
	}

	//渐进式图片
	static ProgressiveJpegConfig mProgressiveJpegConfig = new ProgressiveJpegConfig() {
		@Override
		public int getNextScanNumberToDecode(int scanNumber) {
			return scanNumber + 2;
		}

		public QualityInfo getQualityInfo(int scanNumber) {
			boolean isGoodEnough = (scanNumber >= 5);
			return ImmutableQualityInfo.of(scanNumber, isGoodEnough, false);
		}
	};
}